/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package control;

import Controlador.Operacion;
import dao.PersonDao;
import entity.ActualUser;
import entity.Person;
import Modelo.Numero;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

/**
 *
 * @author Laarguelless
 */
public class TransactionControl {

    /**Constant fot the operations result. Success. 
     */
    private static final int Zero = 0;
    /**Constant fot the operations result. 
     */
    private static final int One = -1;
    /**Constant fot the operations result. 
     */
    private static final int Two = -2;
    /**Constant fot the operations result. 
     */
    private static final int Three = -3;
    
    /**The entityManagerFactory to create the EntityManager. 
     */
    private static EntityManagerFactory emf = Persistence.createEntityManagerFactory("CajeroAutomaticoPU");
    /**The object to do the mathematical operations. 
     */
    private Operacion operation;
    /**The Dao Object to do the operations. 
     */
    private PersonDao personDao;

    /**Default Constructor. 
     */
    public TransactionControl() {
        operation = new Operacion();
        personDao = new PersonDao();
    }
    
    /**Do the consignment operation.
     * @return void
     */
    public int consignment() {
        ActualUser user = ActualUser.getInstance();
        double amount = user.getBalanceOnChange();
        /**
         * The amount given, is not between the limits
         */
        if (!validateConsignment(amount)) {
            return One;
        }

        Numero balance = new Numero();
        balance.setValor(user.getBalance());

        Numero consign = new Numero();
        consign.setValor(amount);


        double nextAmount = operation.sumar(balance, consign).getValor();

        user.setBalance(nextAmount);

        EntityManager em = emf.createEntityManager();

        try {

            em.getTransaction().begin();
            Person person = personDao.searchByUsername(user.getUsername(), em).get(0);
            person.setBalance(user.getBalance());
            personDao.updatePass(person, em);
            em.getTransaction().commit();
            return Zero;
        } catch (Exception e) {
            return Two;
        } finally {
            em.close();
        }
    }
    
    /**This method register a retirement of One person on the database and return the result of the transaction.
     * @return The number identifying the result of the operation
     */
    public int retirement() {
        ActualUser user = ActualUser.getInstance();
        /**
         * The amount given, is not between the limits
         */
        double amount = user.getBalanceOnChange();
        if (!validateRetiement(amount)) {
            return One;
        }

        Numero balance = new Numero();
        balance.setValor(user.getBalance());

        Numero retirment = new Numero();
        retirment.setValor(amount);

        double nextBalance = operation.restar(balance, retirment).getValor();
        /**
         * The customer does not have the enough balance to de the retirement
         */
        if (nextBalance < 0) {
            return Two;
        }
        user.setBalance(nextBalance);
        user.setBalanceOnChange(0);
        EntityManager em = emf.createEntityManager();
        try {
            em.getTransaction().begin();

            Person person = personDao.searchByUsername(user.getUsername(), em).get(0);
            person.setBalance(user.getBalance());

            personDao.updatePass(person, em);
            em.getTransaction().commit();
            return Zero;
        } catch (Exception ex) {
            return Three;
        } finally {
            em.close();
        }
    }
    /**Validates the amount of the consigment.
     * @param amount Amount to validate
     * @return boolean
     */
    private boolean validateConsignment(final double amount) {
        double min = 10000;
        double max = 1000000;
        if (amount % min != 0 || amount > max || amount < 0) {
            return false;
        }
        return true;
    }

    /**Validates the amount of the retirement.
     * @param amount Amount to Validate
     * @return boolean
     */
    private boolean validateRetiement(final double amount) {
        double min = 10000;
        double max = 400000;
        if (amount < min || amount > max) {
            return false;
        }
        return true;
    }

    /**Do the consignemnt operation to New Customers. The initial Balance.
     * @param user User to consign the amount.
     * @param amount Initial amount for the user.
     * @return int
     */
    public int consignment(final Person user, final Double amount) {
        /**
         * El monto dado no está entre los límites dados en la lógica de negocio
         */
        if (!validateConsignment(amount)) {
            return One;
        }

        Numero balance = new Numero();
        balance.setValor(user.getBalance());

        Numero consign = new Numero();
        consign.setValor(amount);
        
        EntityManager em = emf.createEntityManager();

        try {

            em.getTransaction().begin();
            Person person = personDao.searchByUsername(user.getUserName(), em).get(0);
            person.setBalance(user.getBalance());
            personDao.updatePass(person, em);
            em.getTransaction().commit();
            return Zero;
        } catch (Exception e) {
            return Two;
        } finally {
            em.close();
        }
    }

    /**This method return the balance of a person from the database.
     * @param username The customer's username to di the operation.
     * @return double
     */
    public double getBalance(final String username) {
        EntityManager em = emf.createEntityManager();
        Person user = personDao.searchByUsername(username, em).get(0);
        return user.getBalance();
    }
}
